package copy.express.process.suffix;

import copy.application.Application;
import copy.application.Process;
import copy.express.ParseNodeStack;
import copy.express.pojo.Node;
import copy.express.pojo.NodeStack;
import copy.express.pojo.NodeType;
import copy.express.pojo.type.Type;

import java.util.Stack;

/**
 * 将NodeStack
 *      由于中缀表达式 转 后缀表达式
 */
public abstract class AbsSuffixExpress implements ParseNodeStack, Process {

    protected Application application = Application.getScanSingleBean();

    @Override
    public Stack<NodeType> toSuffixStack(NodeStack nodeStack){
        //临时栈
        Stack<NodeType> tempStack = new Stack<>();
         //输出栈
        Stack<NodeType> outStack = new Stack<>();
        for (NodeType node : nodeStack.getQueue()) {
            //如果是符号
            if (node.getType() instanceof Type.SymbolEnum){
                if (tempStack.size()==0){
                    tempStack.push(node);
                    continue;
                }else{

                    if ( ( (Type.SymbolEnum)node.getValue() ) == Type.SymbolEnum.RIGHT ){
                        //弹出到左括号间的数据
                        popLeftAndRightNode(tempStack,outStack);

                    }else{
                        //栈顶元素
                        NodeType max = tempStack.pop();
                        maxStackNode(tempStack,outStack,max,node);
                    }
                }
            }else{//数据直接输出
                outStack.push(node);
            }
        }
        //临时栈全部出栈
        int size = tempStack.size();
        for (int i = 0; i < size; i++) {
            outStack.push(tempStack.pop());
        }
        //更新NodeStack
        nodeStack.removeAllElements();
        for (int i = 0; i < outStack.size(); i++) {
            nodeStack.add(i,outStack.get(i));
        }
        return outStack;
    }

    private void popLeftAndRightNode(Stack<NodeType> tempStack,Stack<NodeType> outStack){
        NodeType maxNode = null;
        while (true){
            maxNode = tempStack.pop();
            //栈顶
            Type.SymbolEnum maxSymbolEnum = (Type.SymbolEnum)maxNode.getValue();
            if (maxSymbolEnum == Type.SymbolEnum.LEFT){
                return;
            }else{
                outStack.push(maxNode);
            }
        }

    }

    private void maxStackNode(Stack<NodeType> tempStack,Stack<NodeType> outStack,NodeType maxNode,NodeType curNode){
        //栈顶
        Type.SymbolEnum maxSymbolEnum = (Type.SymbolEnum)maxNode.getValue();
        //当前元素
        Type.SymbolEnum currentSymbolEnum = (Type.SymbolEnum)curNode.getValue();
        //准备入栈
        if ( currentSymbolEnum.rate > maxSymbolEnum.rate || maxSymbolEnum == Type.SymbolEnum.LEFT){
            tempStack.push(maxNode);
            tempStack.push(curNode);
        }else{
            if ( ( (Type.SymbolEnum)maxNode.getValue() ) != Type.SymbolEnum.LEFT){
                //准备出栈
                outStack.push(maxNode);
                //继续判断栈顶元素: 递归 -->继续出栈
                if (tempStack.size()>0){
                    maxStackNode(tempStack,outStack,tempStack.pop(),curNode);
                }else{
                    //找到合适位置
                    tempStack.push(curNode);
                }

            }else{
                //由于是左括号,不出栈.特殊处理
                tempStack.push(maxNode);
                tempStack.push(curNode);
            }

        }
    }
}
